package server;
// This file contains material supporting section 3.7 of the textbook:
// "Object Oriented Software Engineering" and is issued under the open-source
// license found at www.lloseng.com 



import java.io.*;

import logic.BookItem;
import logic.BorrowHistory;
import logic.Librarian;
import logic.Message;
import logic.Reader;
import logic.Title;

import ocsf.server.*;

/**
 * This class overrides some of the methods in the abstract 
 * superclass in order to give more functionality to the server.
 */
public class EchoServer extends AbstractServer 
{
	
  //Class variables *************************************************
	
  /**
   * The default port to listen on.
   */
  final public static int DEFAULT_PORT = 5555;
  private static DBhandler db;
  
  //Constructors ****************************************************
  
  /**
   * Constructs an instance of the echo server.
   *
   * @param port The port number to connect on.
   */
  public EchoServer(int port) 
  {
    super(port);
  }

  
  //Instance methods ************************************************
  
  /**
   * This method handles any messages received from the client.
   */
  public void handleMessageFromClient (Object msg, ConnectionToClient client)
  {   
	  System.out.println("handleMessageFromClient:"+((Message)msg).getCommand());
	  Message m;
	  Reader r;
	  BookItem b;
	  m=(Message)msg;
	 
	  	  
		
		int flag;
	
	  	 if(m.getCommand().equals("Add Reader"))
		  {
			  r=(Reader)m.getObjects();
			  flag=db.AddReader(r);
			  if(flag==0)
			  {
	            m=new Message ("user already exists",null);	
	            try {
					client.sendToClient(m);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			  }
			  if(flag==1)
			  {
				  m=new Message ("user  added successfully",null);
				  try {
					client.sendToClient(m);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			  }
			  else{
				  m=new Message ("error adding reader",null);
				  try {
					client.sendToClient(m);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				  
			  }
		  }
	  	 
	  	 
	  	if(m.getCommand().equals("Search Book"))
	  	{
			
	  		m= (Message)db.SearchBook((Message)m);
	  		//t=(Title) m.getObjects();
	  		
	  			try {
	  				System.out.println("send to client");
					client.sendToClient(m);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
	  		}
	  	

	  	 
	  	 
	  	 
	  	if(m.getCommand().equals("login"))
	  	{
	  		m= (Message)db.login((Reader)m.getObjects());
	  	
	  			try {
	  				System.out.println("send to client");
					client.sendToClient(m);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
	  	}
	  	if(m.getCommand().equals("logout"))
	  	{
	  		m=db.logout((Reader)m.getObjects());
	  		try {
  				System.out.println("send to client");
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  	}
	  	
	  	if(m.getCommand().equals("Edit Book")){
	  		m= (Message)db.EditBook((Title)m.getObjects());
  			try {
  				System.out.println("send to client");
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  		
	  		
	  	}
	  	if(m.getCommand().equals("Add Book")){
	  		try {
				m= (Message)db.AddBook((Title)m.getObjects());
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
	  		//m= (Message)db.AddBook((Object[])m.getObjects());
  			try {
  				System.out.println("send to client");
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  	}
	  	if(m.getCommand().equals("Delete Book")){
	  		m= (Message)db.DeleteBook((BookItem)m.getObjects());
  			try {
  				System.out.println("send to client");
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  	}
	  	if(m.getCommand().equals("Order Book")){
	  		m= (Message)db.orderBook((Object[])m.getObjects());
  			try {
  				System.out.println("send to client");
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  	}
	  	if(m.getCommand().equals("Get Book")){
	  		m= (Message)db.GetBook((BookItem)m.getObjects());
  			try {
  				System.out.println("send to client");
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  	}
	  	
	  	if(m.getCommand().equals("Lend Book"))
	  	{
	  		// Object[] o =new Object[2];
	  		//o=(Object[])m.getObjects();
			  Object[] array = new Object[2];
			  array=(Object[]) m.getObjects();
	  		b= (BookItem)array[0];
	  		r= (Reader)array[1];
	  		System.out.println("df"+r.getReaderId());
	  		System.out.println("lend login "+b.getCatalogNumber()+" "+ r.getReaderId());
	  		
	  		m= (Message)db.Lend(r,b);
	  		
	  		
	  			
	  		try {
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  	}

	  	if(m.getCommand().equals("Freeze Reader Card"))
	  	{
	  		 System.out.println("login to freaze");
	  		r=(Reader)m.getObjects();
	  		m= (Message)db.Freeze(r);
	  	  	try {
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  	
	
	  	}
	  	
	  	if(m.getCommand().equals("Return Book")){
			String disc;
	  		Object[] array = new Object[3];
			array=(Object[]) m.getObjects();
	  		b= (BookItem)array[0];
	  		r= (Reader)array[1];
	  		disc=(String)array[2];
	  		m= (Message)db.ReturnBook(r,b,disc);
  			try {
  				System.out.println("send to client");
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  	}

	  	
	  	if(m.getCommand().equals("Reader Edit")){
	  		m= (Message)db.ViewReaderEdit((Reader)m.getObjects());
  			try {
  				System.out.println("send to client");
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  	}
	  	
	  	
	  	if(m.getCommand().equals("Reader History"))
	  	{
	  		m = (Message)db.ReaderHistory((Reader)m.getObjects());
	  		
  			try {
  				System.out.println("send to client");
  				
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  	}
	  	
	  	if(m.getCommand().equals("LibrarianExtend"))
	  	{
			Object[] array = new Object[3];
			array=(Object[]) m.getObjects();
			BorrowHistory h;
			Librarian l;
	  		h= (BorrowHistory)array[0];
	  		r= (Reader)array[1];	
	  		l=(Librarian)array[2];
	  		m = (Message)db.LibrarianExtend(r,h,l);
  			try {
  				System.out.println("send to client");
  				
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  	}
	  	
	  	if(m.getCommand().equals("ReaderExtend"))
	  	{
			Object[] array = new Object[2];
			array=(Object[]) m.getObjects();
			BorrowHistory h;
	  		h= (BorrowHistory)array[0];
	  		r= (Reader)array[1];		
	  		m = (Message)db.ReaderExtend(r,h);
  			try {
  				System.out.println("send to client");
  				
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  	}
	  	if(m.getCommand().equals("Manager Get Details"))
	  	{
	  		m = (Message)db.ManagerGetDetails();
	  		
  			try {
  				System.out.println("send to client");
  				
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  		
	  	}
	  	if(m.getCommand().equals("GetReader"))
	  	{
	  		Integer i =(Integer)m.getObjects();
	  		m = (Message)db.getReader(i.intValue());
	  		
  			try {
  				System.out.println("send to client");
  				
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  		
	  	}
	  	if(m.getCommand().equals("Get Periodic Report"))
	  	{
	  		m = (Message)db.GetPeriodicReport();
  			try {
  				System.out.println("send to client");
  				
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  		
	  	}
	  	
	  	if(m.getCommand().equals("Get Lend Report"))
	  	{
	  		m = (Message)db.GetLendReport();
  			try {
  				System.out.println("send to client");
  				
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  		
	  	}
	  	
	  	if(m.getCommand().equals("Get Late In Return Report"))
	  	{
	  		m = (Message)db.GetLateInReturnReport();
  			try {
  				System.out.println("send to client");
  				
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  		
	  	}
	  	if(m.getCommand().equals("ExternalLockRequest"))
	  	{
	  		Integer i=(Integer)m.getObjects();
	  		m = (Message)db.ExternalLockRequest(i.intValue());
  			try {
  				System.out.println("send to client");
  				
				client.sendToClient(m);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	  		
	  	}
	  	
  }

	  

    
  /**
   * This method overrides the one in the superclass.  Called
   * when the server starts listening for connections.
   */
  protected void serverStarted()
  {
    System.out.println
      ("Server listening for connections on port " + getPort());
  }
  
  /**
   * This method overrides the one in the superclass.  Called
   * when the server stops listening for connections.
   */
  protected void serverStopped()
  {
    System.out.println
      ("Server has stopped listening for connections.");
  }
  
  //Class methods ***************************************************
  
  /**
   * This method is responsible for the creation of 
   * the server instance (there is no UI in this phase).
   *
   * @param args[0] The port number to listen on.  Defaults to 5555 
   *          if no argument is entered.
   */
  public static void main(String[] args) 
  {
    int port = 0; //Port to listen on
   
    try
    {
      port = Integer.parseInt(args[0]); //Get port from command line
    }
    catch(Throwable t)
    {
      port = DEFAULT_PORT; //Set port to 5555
    }
    
  	try {
	  	
			db = new DBhandler();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	  	
	
    EchoServer sv = new EchoServer(port);
    
    try 
    {
      sv.listen(); //Start listening for connections
    } 
    catch (Exception ex) 
    {
      System.out.println("ERROR - Could not listen for clients!");
    }
  }
}
//End of EchoServer class
